package com.broada.apm.utils;

import java.nio.charset.Charset;
import java.util.Date;
import java.util.concurrent.atomic.AtomicLong;

import com.broada.apm.model.ApplicationSystem;
import com.broada.apm.model.Dimension;
import com.broada.apm.model.Resource;
import com.broada.apm.model.Service;
import com.google.common.hash.Hashing;

public class IdUtils {
    private static AtomicLong idseq = new AtomicLong();
    private static String idprefix = Long.toString(System.currentTimeMillis(), 36) + "-";

    public static String strSeq() {
        return new StringBuffer(idprefix).append(idseq.getAndIncrement()).toString();
    }

    public static String nodeId(long ip) {
        return Hashing.murmur3_32().hashLong(ip).toString();
    }

    public static String resourceId(int l4protocol, long ip, int port, int protocol, String uri) {
        return Hashing
                .murmur3_32()
                .hashString(
                        new StringBuffer().append(l4protocol).append("-").append(protocol).append("://").append(ip)
                                .append(":").append(port).append("/").append(uri).toString(), Charset.defaultCharset())
                .toString();
    }
    
    public static String resourceId(String uri) {
        return Hashing
                .murmur3_32()
                .hashString(
                        new StringBuffer().append(uri).toString(), Charset.defaultCharset())
                .toString();
    }

    public static String resourceIdWithApp(String appId, int l4protocol, long ip, int port, int protocol, String uri) {
        return Hashing
                .murmur3_32()
                .hashString(
                        new StringBuffer(appId).append("-").append(l4protocol).append("-").append(protocol)
                                .append("://").append(ip).append(":").append(port).append("/").append(uri).toString(),
                        Charset.defaultCharset()).toString();
    }

    public static String serviceIdWithApp(String appId, int l4protocol, long ip, int port) {
        return new StringBuffer(appId).append("-").append(serviceId(l4protocol, ip, port)).toString();
    }

    public static String serviceIdWithApp(String appId, String serviceId) {
        return new StringBuffer(appId).append("-").append(serviceId).toString();
    }

    public static String serviceId(String appId, String appServiceId) {
        String prefix = appId + "-";
        if (appServiceId.indexOf(prefix) > -1)
            return appServiceId.replace(prefix, "");
        return appServiceId;
    }

    public static String serviceId(int l4protocol, long ip, int port) {
        return Hashing
                .murmur3_32()
                .hashString(new StringBuffer().append(ip).append(":").append(port).toString(), Charset.defaultCharset())
                .toString();
    }

    public static String domainId(String serviceId, String domain) {
        return Hashing
                .murmur3_32()
                .hashString(new StringBuffer().append(serviceId).append("-").append(domain).toString(),
                        Charset.defaultCharset()).toString();
    }

    public static String counterId(ApplicationSystem application, Service service, Resource resource, Dimension dimension) {
        return new StringBuffer(application == null ? "NONAPP" : application.getId()).append("-")
                .append(service == null ? "NOSRV" : service.getId()).append("-")
                .append(resource == null ? "NORES" : resource.getId()).append("-")
                .append(dimension == null ? "NODIM" : dimension.getType() + "." + dimension.getId()).toString();
    }

    public static String counterId(String applicationId, String serviceId, String resourceId, String dimensionType,
            String dimensionId) {
        return new StringBuffer(applicationId == null ? "NONAPP" : applicationId).append("-")
                .append(serviceId == null ? "NOSRV" : serviceId).append("-")
                .append(resourceId == null ? "NORES" : resourceId).append("-")
                .append(dimensionType == null ? "NODIM" : dimensionType + "." + dimensionId).toString();
    }

    public static String hash(String str) {
        return Hashing.murmur3_32().hashString(str, Charset.defaultCharset()).toString();
    }

    public static String statusId(String applicationId, String serviceId, String resourceId, Date date, String isBusiness) {
        StringBuffer sb = new StringBuffer();
        sb.append(applicationId == null ? "NONAPP" : applicationId).append("_");
        sb.append(serviceId == null ? "NOSRV" : serviceId).append("_");
        sb.append(resourceId == null ? "NORES" : resourceId);
        sb.append(isBusiness == null ? "" : isBusiness);
        // sb.append("_").append(DateUtils.getFragmentInMinutes(date,
        // Calendar.HOUR_OF_DAY));
        return sb.toString();
    }

    public static String counterId(String applicationId, String serviceId, String resourceId, Dimension dimension) {
        StringBuffer sb = new StringBuffer(applicationId == null ? "NONAPP" : applicationId);
        sb.append("-").append(serviceId == null ? "NOSRV" : serviceId);
        sb.append("-").append(resourceId == null ? "NORES" : resourceId);
        sb.append("-").append(dimension == null ? "NODIM" : dimension.getType() + "." + dimension.getId());
        return sb.toString();
    }
    
    public static String TransactionChannelId(String appId, String serviceId,String channelName) {
    	return Hashing
                .murmur3_32()
                .hashString(new StringBuffer().append(appId).append("-").append(serviceId)
                		.append("-").append(channelName).toString(),
                        Charset.defaultCharset()).toString();
	}
    
    public static String TransactionTypeId(String appId, String serviceId, String typeName) {
    	return Hashing
                .murmur3_32()
                .hashString(new StringBuffer().append(appId).append("-").append(serviceId)
                		.append("-").append(typeName).toString(),
                        Charset.defaultCharset()).toString();
	}
    
    final static String chars = "0123456789abcdefghijklmnopqrestvywxzABCDEFGHIJKLMNOPQRESTVWXYZ";
    private static String longToString(long l) {
        int s = chars.length();
        StringBuffer sb = new StringBuffer();
        while (l > s) {
            long m = l % s;
            sb.append(chars.charAt((int) m));
            l = l / s;
        }
        return sb.reverse().toString();
    }
    private static long stringToLong(String str) {
        long r = 0;
        final int s = chars.length();
        for (int i = 0; i < str.length(); i++) {
            r = r*s+ chars.indexOf(str.charAt(i)) ;
        }
        return r;
    }
}
